package com.easymin.weixin.controller.v5;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSONObject;
import com.easymin.weixin.common.WxUtils;
import com.easymin.weixin.common.api.DaijiaApi;
import com.easymin.weixin.common.api.GasApi;
import com.easymin.weixin.controller.v5.utils.ErrorMapV5;
import com.easymin.weixin.controller.v5.utils.ResultV5;
import com.easymin.weixin.entity.WxAccount;
import com.easymin.weixin.entity.WxApplication;
import com.easymin.weixin.manager.WxAccountManager;
import com.easymin.weixin.manager.WxApplicationManager;
import com.google.common.base.Preconditions;

/**
 * 加油站请求控制器
 * @author zane
 *
 */
@Controller
@RequestMapping("v5/gas")
public class JiaYouZhanController {
	
	private static final Logger logger = LoggerFactory.getLogger(DaijiaApi.class);

	private static final String WX_ACCESS_TOKEN = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={appid}&secret={secret}";

	private static final String WX_JSAPI_TICKET = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={access_token}&type=jsapi";
	
	@Autowired
	private WxAccountManager wxAccountManager;

	@Autowired
	private RestTemplate restTemplate;

	@Autowired
	private GasApi gasApi;
	
	@Autowired
	private WxApplicationManager wxApplicationManager;
	
	/**
	 * 获取附近加油站
	 * @param brand 品牌 
	 * @param gasNum 油号
	 * @param privilege 特权
	 * @param lng 经度
	 * @param lat 纬度
	 * @param page 页码
	 * @param rows 条数
	 * @param appKey 系统key
	 * @throws Exception 请求异常
	 */
	@ResponseBody
	@RequestMapping(value="stations", method=RequestMethod.GET)
	public ResultV5 gasStationList
	( @RequestParam(required = false, value = "brand") String brand,
      @RequestParam(required = false, value = "gasNum") String gasNum,
      @RequestParam(required = false, value = "privilege") Boolean privilege,
      @RequestParam(required = false, value = "page") Integer page,
      @RequestParam(required = false, value = "rows") Integer rows,
      @RequestParam("lng") Double lng,
      @RequestParam("lat") Double lat,
      @RequestParam("appKey") String appKey) 
	 throws Exception {
		ResultV5 result = null;
		try {
			WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
			if (null == wxApplication) {
				logger.error("无该应用");
				return new ResultV5(-1, "无该应用");
			}
			result = gasApi.gasStationList(brand, gasNum, privilege, lng, lat, page, rows, appKey);
		} catch (Exception e) {
			logger.error("系统异常");
			result = new ResultV5(-1, "系统异常");
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * 查询所有的加油站品牌
	 * @param appKey 系统key
	 * @return ResultV5
	 * @throws Exception  请求异常
	 */
	@ResponseBody
	@RequestMapping(value="brands", method=RequestMethod.GET)
	public ResultV5 brands 
	(@RequestParam("appKey") String appKey)
	throws Exception {
		ResultV5 result = null;
		try {
			WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
			if (null == wxApplication) {
				logger.error("无该应用");
				return new ResultV5(-1, "无该应用");
			}
			result = gasApi.brands(appKey);
		} catch (Exception e) {
			logger.error("系统异常");
			result = new ResultV5(-1, "系统异常");
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * 加油站详情[点击加油站列表时的跳转时使用此接口]
	 * @param id 加油站Id
	 * @param appKey 系统key
	 * @return ResultV5
	 * @throws Exception 请求异常
	 */
	@ResponseBody
	@RequestMapping(value="station", method=RequestMethod.GET)
	public ResultV5 stationInfo 
	(@RequestParam("id") Long id,
	 @RequestParam("appKey") String appKey) 
	throws Exception {
		ResultV5 result = null;
		try {
			WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
			if (null == wxApplication) {
				logger.error("无该应用");
				return new ResultV5(-1, "无该应用");
			}
			result = gasApi.stationInfo(id, appKey);
		} catch (Exception e) {
			logger.error("系统异常");
			result = new ResultV5(-1, "系统异常");
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * 获取加油站评价
	 * @param gasId 加油站Id
	 * @param appKey 系统Key
	 * @param page 页码
	 * @param rows 条数
	 * @return ResultV5
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping(value="reviews", method=RequestMethod.GET)
	public ResultV5 reviews 
	(@RequestParam("gasId") Long gasId,
	 @RequestParam("appKey") String appKey,
     @RequestParam(required = false,value = "page") Integer page,
     @RequestParam(required = false,value = "rows") Integer rows) 
	throws Exception {
		ResultV5 result = null;
		try {
			WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
			if (null == wxApplication) {
				logger.error("无该应用");
				return new ResultV5(-1, "无该应用");
			}
			result = gasApi.reviews(gasId, appKey, page, rows);
		} catch (Exception e) {
			logger.error("系统异常");
			result = new ResultV5(-1, "系统异常");
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * 支付加油站订单时的加油站及其客户优惠券的信息
	 * @param passengerId 客户ID
	 * @param gasStationId 加油站ID
	 * @param appKey 系统key
	 * @return ResultV5
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping(value="coupons", method=RequestMethod.GET)
	public ResultV5 orderStationInfo 
	(@RequestParam(required = true, value = "passengerId") Long passengerId,
	 @RequestParam(required = true, value = "gasStationId") Long gasStationId,
	 @RequestParam(required = true, value = "appKey") String appKey)
	throws Exception {
		ResultV5 result = null;
		try {
			WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
			if (null == wxApplication) {
				logger.error("无该应用");
				return new ResultV5(-1, "无该应用");
			}
			String server = wxApplication.getAddress();
			if (null == server || server.isEmpty()) {
				logger.error("无效的代驾服务地址");
				return new ResultV5(-1, "无效的代驾服务地址");
			}
			result = gasApi.orderStationInfo(server, passengerId, gasStationId, appKey);
		} catch (Exception e) {
			logger.error("系统异常");
			result = new ResultV5(-1, "系统异常");
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * 加油站订单余额支付
	 * @param passengerId 客户Id
	 * @param gsId 加油站Id
	 * @param gasNum 油号
	 * @param money 加油金额
	 * @param realMoney 实收金额
	 * @param discountMoney 平台优惠
	 * @param couponId 优惠券ID
	 * @param compressorGun 服务号
	 * @param appKey 系统key
	 * @return ResultV5
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping(value="/pay/blance", method=RequestMethod.POST)
	public ResultV5 paymentByBlance 
	(@RequestParam(required = true, value = "passengerId") Long passengerId,
     @RequestParam(required = true, value = "gsId") Long gsId,
     @RequestParam(required = true, value = "gasNum") String gasNum,
     @RequestParam(required = true, value = "money") BigDecimal money,
     @RequestParam(required = true, value = "realMoney") BigDecimal realMoney,
     @RequestParam(required = true, value = "discountMoney") BigDecimal discountMoney,
     @RequestParam(required = false,value = "couponId") Long couponId,
     @RequestParam(required = false,value = "compressorGun") String compressorGun,
     @RequestParam(required = true, value = "appKey")String appKey) 
	throws Exception {
		ResultV5 result = null;
		try {
			WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
			if (null == wxApplication) {
				logger.error("无该应用");
				return new ResultV5(-1, "无该应用");
			}
			String server = wxApplication.getAddress();
			if (null == server || server.isEmpty()) {
				logger.error("无效的代驾服务地址");
				return new ResultV5(-1, "无效的代驾服务地址");
			}
			result = gasApi.paymentByBlance(server, passengerId, gsId, gasNum, money, 
					realMoney, discountMoney, couponId, compressorGun, appKey);
		} catch (Exception e) {
			logger.error("系统异常");
			result = new ResultV5(-1, "系统异常");
			e.printStackTrace();
		}
		return result;
	}
	
	
	@ResponseBody
	@RequestMapping(value="/pay/wx", method=RequestMethod.POST)
	public ResultV5 paymentByWX 
	(@RequestParam(required = true, value = "passengerId") Long passengerId,
	 @RequestParam(required = true, value = "openId") String openId,
	 @RequestParam(required = true, value = "appId") String appId,
     @RequestParam(required = true, value = "gsId") Long gsId,
     @RequestParam(required = true, value = "gasNum") String gasNum,
     @RequestParam(required = false,value = "compressorGun") String compressorGun,
     @RequestParam(required = true, value = "money") BigDecimal money,
     @RequestParam(required = true, value = "realMoney") BigDecimal realMoney,
     @RequestParam(required = true, value = "discountMoney") BigDecimal discountMoney,
     @RequestParam(required = false, value = "couponId") Long couponId,
     @RequestParam(required = true, value = "appKey")String appKey,
     HttpServletRequest request) 
	throws Exception {
		ResultV5 result = null;
		try {
			WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
			if (null == wxApplication) {
				logger.error("无该应用");
				return new ResultV5(-1, "无该应用");
			}
			WxAccount wxAccount = wxAccountManager.findBy(appId, wxApplication.getId());
			Preconditions.checkArgument(null != wxAccount, "appid错误");
			String server = wxApplication.getAddress();
			if (null == server || server.isEmpty()) {
				logger.error("无效的代驾服务地址");
				return new ResultV5(-1, "无效的代驾服务地址");
			}
			JSONObject jsonObject = gasApi.paymentByWX(server, passengerId, openId, gsId, gasNum, 
					compressorGun, money, realMoney, discountMoney, couponId, appKey);
			
			// 判断是否来自微信
			StringBuilder sb = new StringBuilder();
			sb.append(request.getScheme());
			sb.append("://");
			sb.append(request.getServerName());
			int port = request.getServerPort();
			if (port != 80) {
				sb.append(":").append(port);
			}
			sb.append(request.getRequestURI());
			String queryString = request.getQueryString();
			if (StringUtils.isNotBlank(queryString)) {
				sb.append("?");
				sb.append(queryString);
			}

			// 获取微信AccessToken
			String response = restTemplate.getForObject(WX_ACCESS_TOKEN, String.class, wxAccount.getWxappId(),
					wxAccount.getAppsecret());
			JSONObject ac = JSONObject.parseObject(response);

			if (ac.containsKey("access_token")) {
				String accessToken = ac.getString("access_token"); // 获取微信access_token
				// 获取jsapi_ticket
				String resp = restTemplate.getForObject(WX_JSAPI_TICKET, String.class, accessToken);
				JSONObject ticketJson = JSONObject.parseObject(resp);
				if (ticketJson.containsKey("ticket")) {
					String ticket = ticketJson.getString("ticket");
					jsonObject.put("jsapi_ticket", ticket);
					Map<String, Object> signParams = new HashMap<>();
					signParams.put("jsapi_ticket", ticket);
					signParams.put("timestamp", jsonObject.getString("timeStamp"));
					signParams.put("url", sb.toString());
					signParams.put("noncestr", jsonObject.getString("nonceStr"));
					jsonObject.put("signature", WxUtils.buildSha1Sign(signParams));

					result = ErrorMapV5.ERR_SUCCESS;
					result.setData(jsonObject);
					return result;
				}
			}
		} catch (Exception e) {
			logger.error("系统异常");
			result = new ResultV5(-1, "系统异常");
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * 客户订单列表
	 * @param passengerId 客户Id
	 * @param page 页码
	 * @param rows 条数
	 * @param appKey 系统key
	 * @return ResultV5
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping(value="orders", method=RequestMethod.GET)
	public ResultV5 orders 
	(@RequestParam("passengerId") Long passengerId,
     @RequestParam("page") Integer page,
     @RequestParam("rows") Integer rows,
     @RequestParam("appKey") String appKey) 
	throws Exception {
		ResultV5 result = null;
		try {
			WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
			if (null == wxApplication) {
				logger.error("无该应用");
				return new ResultV5(-1, "无该应用");
			}
			result = gasApi.orders(passengerId, page, rows, appKey);
		} catch (Exception e) {
			logger.error("系统异常");
			result = new ResultV5(-1, "系统异常");
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * 订单信息
	 * @param id 订单Id
	 * @param appKey 系统key
	 * @return ResultV5
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping(value="order", method=RequestMethod.GET)
	public ResultV5 order
	(@RequestParam("id") Long id,
	 @RequestParam("appKey") String appKey)
	throws Exception {
		ResultV5 result = null;
		try {
			WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
			if (null == wxApplication) {
				logger.error("无该应用");
				return new ResultV5(-1, "无该应用");
			}
			result = gasApi.order(id, appKey);
		} catch (Exception e) {
			logger.error("系统异常");
			result = new ResultV5(-1, "系统异常");
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * 订单评价
	 * @param gasStationId 加油站Id
	 * @param gasStationName 加油站名称
	 * @param orderNo 订单号
	 * @param serviceNo 加油站服务号
	 * @param clientName 客户姓名
	 * @param clientPhone 客户电话
	 * @param clientPhoto 客户头像
	 * @param score 评分
	 * @param content 内容
	 * @param appKey 系统key
	 * @return ResultV5
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping(value="review", method=RequestMethod.POST)
	public ResultV5 review 
	(@RequestParam("gasStationId") Long gasStationId,
     @RequestParam("gasStationName") String gasStationName,
     @RequestParam("serviceNo") String serviceNo,
     @RequestParam("clientName") String clientName,
     @RequestParam("clientPhone") String clientPhone,
     @RequestParam("score") Double score,
     @RequestParam("content") String content,
     @RequestParam("appKey") String appKey,
     @RequestParam(required = false,value = "orderNo") String orderNo,
     @RequestParam(required = false,value = "clientPhoto") String clientPhoto) 
	throws Exception {
		ResultV5 result = null;
		try {
			WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
			if (null == wxApplication) {
				logger.error("无该应用");
				return new ResultV5(-1, "无该应用");
			}
			result = gasApi.review(gasStationId, gasStationName, orderNo, serviceNo, 
					clientName, clientPhone, clientPhoto, score, content, appKey);
		} catch (Exception e) {
			logger.error("系统异常");
			result = new ResultV5(-1, "系统异常");
			e.printStackTrace();
		}
		return result;
	}
}